package com.hjy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hjy.common.constants.TokenConstants;
import com.hjy.common.domain.request.GoodsReq;
import com.hjy.common.domain.response.GoodsRes;
import com.hjy.common.result.Goods;
import com.hjy.common.result.Result;
import com.hjy.common.result.Type;
import com.hjy.common.result.User;
import com.hjy.common.utils.JwtUtils;
import com.hjy.mapper.GoodsMapper;
import com.hjy.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.beans.Transient;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 列表展示
     */
    @Override
    public List<GoodsRes> goodsList(GoodsReq req) {

        String redisKey = "goodsList:list:";
        String s = stringRedisTemplate.opsForValue().get(redisKey);
        if (null == s){
            List<GoodsRes> list = goodsMapper.goodsList(req);
            stringRedisTemplate.opsForValue().set(redisKey, JSONObject.toJSONString(list));
        }
        System.out.println("=========="+JSONObject.toJSONString(s));
        return JSONObject.parseArray(s, GoodsRes.class);
    }
    /**
     * 回显
     */
    @Override
    public Goods byId(Integer id) {
        Goods byId = goodsMapper.byId(id);
        return byId;
    }
    /**
     * 购买 商品
     */
    @Transient
    @Override
    public Result money(Goods goods) {

        //获取锁对象
        final String NAME = "name";
        RLock lock = redissonClient.getLock(NAME);

        Goods byId = goodsMapper.byId(goods.getId());
        double moneys = goods.getPrice() * goods.getNum();
        //判断 用户金额是否够
        if (getUserInfo().getMoney()<moneys){
            throw new RuntimeException("金额不足");
        }
        try {
            //尝试5秒内获取锁，如果获取到了，最长60秒自动释放
            boolean b = lock.tryLock(5L, 60, TimeUnit.MINUTES);
            if (b){
                //判断库存是否足够
                if (byId.getCount()>goods.getNum()){
                    //判断消费金额
                    Double price = goods.getPrice()*0.1;
                    // 扣减用户余额 + 积分
                    goodsMapper.money(moneys,price,goods.getId());
                    //-库存  写个mq
                    rabbitTemplate.convertAndSend("subtract_num",goods,message -> {
                        message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                        return message;
                    });
//                    goodsMapper.count(goods.getNum(),goods.getId());
            }
            }else {
                throw new RuntimeException("库存不足");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            lock.unlock();
        }

        return Result.success("购买成功");

    }
    /**
     * 抽奖
     */
    @Transient
    @Override
    public Result numGoods() {
       // 查看 有多少积分
      User user =  goodsMapper.userByid(1);
        //积分够不够
       if (user.getSore()<2000){
           return Result.error("积分不足");
       }else {
           //减2000积分
           goodsMapper.updSore(1);
           //抽奖  查询数量
           List<Type> counts = goodsMapper.selCount();
           HashMap<String, Integer> map = new HashMap<>();
           counts.forEach((p)->{
               map.put(p.getTypeName(), p.getNum());
           });
           System.out.println("map中的值是："+JSONObject.toJSONString(map));
           int count = new Random().nextInt(10001);
           Set<Map.Entry<String, Integer>> entries = map.entrySet();
           for (Map.Entry<String, Integer> entry : entries) {
               if (count<=entry.getValue()){
                   if (entry.getValue()==1){
                       entries.remove(entry.getKey());
                       // 删除商品
                       goodsMapper.upd(entry.getKey());
                       if (entry.getValue()==0){
                           continue;
                       }
                   }else {
                       map.put(entry.getKey(), entry.getValue() - 1);
                       //数量-1
                       goodsMapper.del(entry.getKey(),1);
                   }
               }
               if (entry.getKey().equals("谢谢惠顾")){
                   return Result.success("谢谢惠顾");
               }else {
                   return Result.success("恭喜你抽到了"+entry.getKey()+"数量还有"+entry.getValue());
               }
           }

       }
            return null;
    }
    /**
     * 登录的回显
     */
    @Override
    public User userById() {
        return goodsMapper.userByid(getUserInfo().getUid());
    }


    /**
     * 获取登录人信息
     */
    public User getUserInfo() {
        String token = request.getHeader(TokenConstants.TOKEN);

        String userKey = JwtUtils.getUserKey(token);

        String s = stringRedisTemplate.opsForValue().get(TokenConstants.TOKEN + userKey);

        return JSONObject.parseObject(s, User.class);
    }

//
//    public static void main(String[] args) {
//           List<String> integers = new ArrayList<>();
//           integers.add("一等将");
//           for (int i = 1; i <= 5; i++) {
//               integers.add("二等将");
//           }
//           for (int i = 1; i <= 10; i++) {
//               integers.add("三等将");
//           }
//           for (int i = 1; i <= 30; i++) {
//               integers.add("四等将");
//           }
//           for (int i = 1; i <= 9954; i++) {
//               integers.add("谢谢惠顾");
//           }
//           Set<String> strings = new HashSet<>(integers);
//           Integer random = new Random().nextInt(9999);
//           System.out.println(random);
//           String s = integers.get(random);
//           System.out.println("获取的商品为："+s);
//           if (random<=30){
//               return Result.success("恭喜你抽到奖品为："+s);
//           }else {
//               return Result.success(s);
//           }
//
//    }

}
